//
//  MZExtensionUIImage.swift
//  MZTool
//
//  Created by gby on 2022/3/7.
//

import UIKit

extension MZKit where Base == UIImage {
    //MARK: 根据颜色创建图片
    public static func color(color: UIColor) -> UIImage?{
        return UIImage.mz.color(color: color, frame: CGRect(x: 0, y: 0, width: 1, height: 1))
    }
    
    public static func color(color: UIColor, frame rect:CGRect) -> UIImage?{
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        context?.fill(rect)
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    //MARK: 创建渐变图片
    public static func create_Gradient(_ size: CGSize, _ data: (statp: CGPoint, endp: CGPoint, colors:[UIColor], locations: [CGFloat ])) -> UIImage?{
        UIGraphicsBeginImageContext(size)
        defer{
            UIGraphicsEndImageContext();
        }
        guard let contentx = UIGraphicsGetCurrentContext() else { return nil }
        //创建CGMutablePathRef
        let path = CGMutablePath();
        //绘制Path
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height);
        path.move(to: CGPoint(x: rect.minX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        path.closeSubpath();
        //绘制渐变
        let colorSpace = CGColorSpaceCreateDeviceRGB();
        let locations:[CGFloat] = data.locations;
        let colors: [CGColor] = data.colors.map { (color) -> CGColor in
            return color.cgColor
        }
        guard let gradient = CGGradient.init(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations) else { return nil }
        contentx.saveGState()
        contentx.addPath(path)
        contentx.clip()
        contentx.drawLinearGradient(gradient, start: data.statp, end: data.endp, options: .drawsAfterEndLocation)
        contentx.restoreGState()
        let img = UIGraphicsGetImageFromCurrentImageContext();
        return img
    }
    
    
    //TODO: 图片
    public struct img {
        //MARK：缩放图片(生成高质量图片）
        public static func scale(ciimage: CIImage, toSize: CGSize) -> UIImage?{
            //将CIImage转成CGImageRef
            let interalRect = ciimage.extent
            guard let imageRef = CIContext(options: nil).createCGImage(ciimage, from: interalRect) else {
                return nil
            }
            //! 创建上下文
            let sideScale = fminf(Float(toSize.width / interalRect.size.width), Float(toSize.width / interalRect.size.height) * Float(UIScreen.main.scale))
            let contextRefWidth: size_t = size_t(ceilf(Float(interalRect.size.width) * sideScale))
            let contextRefHeight: size_t = size_t(ceilf(Float(interalRect.size.height) * sideScale))
            let colorSpaceRef = CGColorSpaceCreateDeviceGray()
            let contextRef = CGContext.init(data: nil, width: contextRefWidth, height: contextRefHeight, bitsPerComponent: 0, bytesPerRow: 0, space: colorSpaceRef, bitmapInfo: CGImageAlphaInfo.none.rawValue)
            
            contextRef?.interpolationQuality = CGInterpolationQuality.none
            contextRef?.scaleBy(x: CGFloat(sideScale), y: CGFloat(sideScale))
            contextRef?.draw(imageRef, in: interalRect)
            
            guard let scaleImagRef = contextRef?.makeImage() else {
                return nil
            }
            return UIImage.init(cgImage: scaleImagRef, scale: UIScreen.main.scale, orientation: .up)
        }
        
        //MARK: 压缩图片质量
        public static func compressQuality(_ image: UIImage, toByte maxLength: Int) -> UIImage {
            var compression: CGFloat = 1
            guard var data = image.jpegData(compressionQuality: compression), data.count > maxLength else {
                return image
            }
            var max: CGFloat = 1
            var min: CGFloat = 0
            for _ in 0..<6 {
                compression = (max + min) / 2
                data = image.jpegData(compressionQuality: compression)!
                if CGFloat(data.count) < CGFloat(maxLength) * 0.9 {
                    min = compression
                } else if data.count > maxLength {
                    max = compression
                } else {
                    break
                }
            }
            MZ.printLog("13========: " + "\(Double(data.count)/(1024*1024))")
            return UIImage(data: data)!
        }
        
        //MARK: 压缩图片尺寸
        public static func compressSize(_ image: UIImage, toByte maxLength: Int) -> UIImage {
            guard var data = image.jpegData(compressionQuality: 1) else { return image }
            MZ.printLog("1========: " + "\(Double(data.count)/(1024*1024))")
            var resultImage: UIImage = image
            var lastDataLength: Int = 0
            while data.count > maxLength, data.count != lastDataLength {
                lastDataLength = data.count
                let ratio: CGFloat = CGFloat(maxLength) / CGFloat(data.count)
                let size: CGSize = CGSize(width: Int(resultImage.size.width * sqrt(ratio)),
                                        height: Int(resultImage.size.height * sqrt(ratio)))
                UIGraphicsBeginImageContext(size)
                resultImage.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
                resultImage = UIGraphicsGetImageFromCurrentImageContext()!
                UIGraphicsEndImageContext()
                data = resultImage.jpegData(compressionQuality: 1)!
            }
            MZ.printLog("2========: " + "\(Double(data.count)/(1024*1024))")
            return resultImage
        }
    }
    
    
    //TODO: 二维码
    public struct QR {
        //MARK: 创建二维码+图片
        public static func img(qrContent: String, qrSize: CGSize, _ centerImg: UIImage?, _ centerSize: CGSize = CGSize.zero, _ inputCorrectionLevel: String = "H") -> UIImage?{
            let filter = CIFilter.init(name: "CIQRCodeGenerator")
            filter?.setDefaults()
            let data = qrContent.data(using: String.Encoding.utf8, allowLossyConversion: true)
            filter?.setValue(data, forKey: "inputMessage")
            filter?.setValue(inputCorrectionLevel, forKey: "inputCorrectionLevel")
            guard let ciimage = filter?.outputImage else {
                return nil
            }
            let extend = ciimage.extent.integral
            let scale = min(qrSize.width/extend.width, qrSize.height/extend.height)
            let transform = CGAffineTransform.init(scaleX: scale, y: scale)
            let img = UIImage.init(ciImage: ciimage.transformed(by: transform))
            
            if centerImg != nil {
                let size = img.size
                UIGraphicsBeginImageContextWithOptions(size, true, UIScreen.main.scale)
                img.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
                var width: CGFloat = 80
                var height: CGFloat = 80
                if centerSize != CGSize.zero {
                    width = centerSize.width
                    height = centerSize.height
                }
                let x: CGFloat = (size.width - width) * 0.5
                let y: CGFloat = (size.height - height) * 0.5
                centerImg!.draw(in: CGRect(x: x, y: y, width: width, height: height))
                let resultImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return resultImage
            }
            return img
        }
        
        //MARK: 创建条形码
        public static func code128Img(qrContent: String, qrSize: CGSize) -> UIImage?{
            let data = qrContent.data(using: String.Encoding.utf8, allowLossyConversion: true)
            let filter = CIFilter.init(name: "CICode128BarcodeGenerator", parameters: [
                "inputMessage": data as Any,
                "inputQuietSpace": NSNumber.init(value: 0.0)
            ])
            guard let ciimage = filter?.outputImage else {
                return nil
            }
            let img = UIImage.mz.img.scale(ciimage: ciimage, toSize: qrSize)
            return img
        }
        
        //MARK: 识别二维码
        public static func scan(source: UIImage?) -> [String]?{
            guard let img = source else { return nil }
            guard let ciimage = img.ciImage else { return nil }
            let content = CIContext(options: nil)
            let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: content, options: [
                CIDetectorAccuracy:CIDetectorAccuracyHigh
            ])
            let features = detector?.features(in: ciimage)
            var allMessage:[String] = []
            for feature in features as! [CIQRCodeFeature] {
                allMessage.append(feature.messageString ?? "")
            }
            return allMessage
        }
        
        //MARK: 二维码合成图片
        public static func combinateCodeImage(codeImage: UIImage, logo: UIImage) -> UIImage?{
            
            UIGraphicsBeginImageContextWithOptions(codeImage.size, true, UIScreen.main.scale)
            // 将codeImage画到上下文中s
            codeImage.draw(in: CGRect(x: 0.0, y: 0.0, width: codeImage.size.width, height: codeImage.size.height))
            // 定义logo的绘制参数
            let logoSide: CGFloat = CGFloat(fminf(Float(codeImage.size.width), Float(codeImage.size.height))) / 4
            let logoX = codeImage.size.width / 2 - logoSide / 2
            let logoY = codeImage.size.height / 2 - logoSide / 2
            let logoRect = CGRect(x: logoX, y: logoY, width: logoSide, height: logoSide)
            let cornerPath = UIBezierPath.init(roundedRect: logoRect, cornerRadius: logoSide / 2)
            cornerPath.lineWidth = 2.0
            UIColor.white.set()
            cornerPath.stroke()
            cornerPath.addClip()
            // 将logo画到上下文中
            logo.draw(in: logoRect)
            // 从上下文中读取image
            let cImage = UIGraphicsGetImageFromCurrentImageContext()
            
            UIGraphicsEndImageContext()
            
            return cImage
        }
    }
}
